<template>
	<view style="position: relative;height: 100%;width:100%;">
		<view ref="container" class="ezfly-card-container" style="position: absolute;left:50%;top:50%;transform: translate(-50%,-50%);">
			
			<view
				class="card"
				v-show="currentItem0"
				:style="{
					width: cardWidth + 'px',
					height: cardHeight + 'px',
					top: top0 + 'px',
					opacity: 1 - Math.abs(top0) / (cardHeight * 3.5),
					zIndex: zIndex0,
					transition: (isUp && maxCurrent === 0) || (!isUp && minCurrent === 0) ? 'none' : '',
					'pointer-events': isAnimating ? 'none' : ''
				}"
				:class="[
					{
						'flying-up': currentIndex == 0 && isUp && isAnimating,
						'flying-down': currentIndex - 1 == 0 && !isUp && isAnimating
					},
					`card${getShowTab[0]}`
				]"
				@touchstart="touchStart($event, 0)"
				@touchmove="touchMove($event, 0)"
				@touchcancel="touchCancel($event, 0)"
				@touchend="touchCancel($event, 0)"
			>
				<div style="width:100%;height:100%;">
					<BaseCard
						:isLast="current == data.length - 1"
						ref="baseCard0"
						v-if="currentItem0 && [0, 1, 2].includes(getShowTab[0])"
						:item="currentItem0"
					/>
				</div>
			</view>
			<view
				class="card"
				v-show="currentItem1"
				:style="{
					width: cardWidth + 'px',
					height: cardHeight + 'px',
					top: top1 + 'px',
					opacity: 1 - Math.abs(top1) / (cardHeight * 3.5),
					zIndex: zIndex1,
					transition: (isUp && maxCurrent === 1) || (!isUp && minCurrent === 1) ? 'none' : ''
				}"
				:class="[
					{
						'flying-up': currentIndex == 1 && isUp && isAnimating,
						'flying-down': currentIndex - 1 == 1 && !isUp && isAnimating
					},
					`card${getShowTab[1]}`
				]"
				@touchstart="touchStart($event, 1)"
				@touchmove="touchMove($event, 1)"
				@touchcancel="touchCancel($event, 1)"
				@touchend="touchCancel($event, 1)"
			>
				<div style="width:100%;height:100%;">
					<BaseCard
						:isLast="current == data.length - 1"
						ref="baseCard1"
						v-if="currentItem1 && [0, 1, 2].includes(getShowTab[1])"
						:item="currentItem1"
					/>
				</div>
			</view>

			<view
				class="card"
				v-show="currentItem2"
				:style="{
					width: cardWidth + 'px',
					height: cardHeight + 'px',
					top: top2 + 'px',
					opacity: 1 - Math.abs(top2) / (cardHeight * 3.5),
					zIndex: zIndex2,
					transition: (isUp && maxCurrent === 2) || (!isUp && minCurrent === 2) ? 'none' : '',
					'pointer-events': isAnimating ? 'none' : ''
				}"
				:class="[
					{
						'flying-up': currentIndex == 2 && isUp && isAnimating,
						'flying-down': currentIndex - 1 == 2 && !isUp && isAnimating
					},
					`card${getShowTab[2]}`
				]"
				@touchstart="touchStart($event, 2)"
				@touchmove="touchMove($event, 2)"
				@touchcancel="touchCancel($event, 2)"
				@touchend="touchCancel($event, 2)"
			>
				<div style="width:100%;height:100%;">
					<BaseCard
						:isLast="current == data.length - 1"
						ref="baseCard2"
						v-if="currentItem2 && [0, 1, 2].includes(getShowTab[2])"
						:item="currentItem2"
					/>
				</div>
			</view>

			<view
				class="card"
				v-show="currentItem3"
				:style="{
					width: cardWidth + 'px',
					height: cardHeight + 'px',
					opacity: 1 - Math.abs(top3) / (cardHeight * 3.5),
					top: top3 + 'px',
					zIndex: zIndex3,
					transition: (isUp && maxCurrent === 3) || (!isUp && minCurrent === 3) ? 'none' : '',
					'pointer-events': isAnimating ? 'none' : ''
				}"
				:class="[
					{
						'flying-up': currentIndex == 3 && isUp && isAnimating,
						'flying-down': currentIndex - 1 == 3 && !isUp && isAnimating
					},
					`card${getShowTab[3]}`
				]"
				@touchstart="touchStart($event, 3)"
				@touchmove="touchMove($event, 3)"
				@touchcancel="touchCancel($event, 3)"
				@touchend="touchCancel($event, 3)"
			>
				<div style="width:100%;height:100%;">
					<BaseCard ref="baseCard3" v-if="currentItem3 && [0, 1, 2].includes(getShowTab[3])" :item="currentItem3" 
						/>
				</div>
			</view>
			<view
				class="card"
				v-show="currentItem4"
				:style="{
					width: cardWidth + 'px',
					height: cardHeight + 'px',
					opacity: 1 - Math.abs(top4) / (cardHeight * 3.5),
					top: top4 + 'px',
					zIndex: zIndex4,
					transition: (isUp && maxCurrent === 4) || (!isUp && minCurrent === 4) ? 'none' : '',
					'pointer-events': isAnimating ? 'none' : ''
				}"
				:class="[
					{
						'flying-up': currentIndex == 4 && isUp && isAnimating,
						'flying-down': currentIndex - 1 < 0 && !isUp && isAnimating
					},
					`card${getShowTab[4]}`
				]"
				@touchstart="touchStart($event, 4)"
				@touchmove="touchMove($event, 4)"
				@touchcancel="touchCancel($event, 4)"
				@touchend="touchCancel($event, 4)"
			>
				<div style="width:100%;height:100%;">
					<BaseCard
						:isLast="current == data.length - 1"
						ref="baseCard4"
						v-if="currentItem4 && [0, 1, 2].includes(getShowTab[4])"
						:item="currentItem4"
					/>
				</div>
			</view>
		</view>
	</view>
</template>

<script>
import BaseCard from './BaseCard.vue';

export default {
	components: {
		BaseCard
	},
	props: {
		data: {
			// 传入的数据
			type: Array,
			default: () => []
		},
		// 卡片背景色
		cardBgColor: {
			type: String,
			default: '#fff'
		},
		// 卡片拖拽方向
		dragDirection: {
			type: String,
			default: 'all' //all,vertical,horizontal
		},
		// 卡片的圆角弧度
		borderRadius: {
			type: Number,
			default: 10
		},
		cat_id: {
			type: String,
			default: ''
		},
	
	},
	data() {
		return {
			throwTriggerDistance: 30, // 卡片触发飞卡效果的距离
			left: 0,
			startLeft: 0,
			startTop: 0,
			isDrag: false,
			isThrow: false,
			needBack: false,
			isAnimating: false,
			top0: 0,
			top1: 0,
			top2: 0,
			top3: 0,
			top4: 0,
			paddingTop: 0,
			cardWidth: 320,
			cardHeight: 530,
			current: 0, // 当前选中card。用来处理滑动飞卡效果
			currentItem0: null,
			currentItem1: null,
			currentItem2: null,
			currentItem3: null,
			currentItem4: null,
			zIndex0: 100,
			zIndex1: 99,
			zIndex2: 98,
			zIndex3: 97,
			zIndex4: 96,
			maxCurrent: 0, // 默认第一个
			minCurrent: 3, // 默认第四个
			currentIndex: 1,
			isUp: true,
			touchStatus: false,
			currentRefIndex: 0
		};
	},
	watch: {
		current(val) {
			this.$emit('getCurrent', val);
		},
	
	},
	computed: {
		getShowTab() {
			let { current } = this;
			switch (current % 5) {
				case 2:
					return [3, 4, 0, 1, 2];
				case 3:
					return [2, 3, 4, 0, 1];
				case 4:
					return [1, 2, 3, 4, 0];
				case 0:
					return [0, 1, 2, 3, 4];
				default:
					return [4, 0, 1, 2, 3];
			}
		}
	},
	async mounted() {
		await this.$nextTick();
		let _this = this;
		_this.cardHeight = window.innerHeight * 0.65;
	},
	methods: {
		init() {
			this.currentItem0 = null;
			this.currentItem1 = this.data[0];
			this.currentItem2 = this.data[1];
			this.currentItem3 = this.data[2];
			this.currentItem4 = this.data[3];
			this.zIndex0 = 100;
			this.zIndex1 = 99;
			this.zIndex2 = 98;
			this.zIndex3 = 97;
			this.zIndex4 = 96;
			this.top0 = 0;
			this.top1 = 0;
			this.top2 = 0;
			this.top3 = 0;
			this.top4 = 0;
			this.maxCurrent = 0;
			this.currentIndex = 1;
			this.isUp = true;
			this.current = 0;
		},



		getDistance: function(x1, y1, x2, y2) {
			var _x = Math.abs(x1 - x2);
			var _y = Math.abs(y1 - y2);
			return Math.sqrt(_x * _x + _y * _y);
		},
		touchStart: function(e, index) {
			this.touchStatus = true;
			setTimeout(() => {
				this.touchStatus = false;
			}, 300);
			this.isUp = true;
			this.isDrag = true;
			let curTouch = e.touches[0];
			this.startTop = curTouch.clientY - this['top' + index];
		},
		touchMove: function(e, index) {
			let { isAnimating, startTop, current, data, maxCurrent, cardHeight, isDrag } = this;
			if (isAnimating || !isDrag) return;
			let curTouch = e.touches[0];
			let v = curTouch.clientY - startTop;
			let res = (this.isUp = v > 0 ? false : true);
			if ((current >= data.length - 1 && res) || (current === 0 && !res)) {
				// console.log("touchMove 不能点了");
				this['top' + index] = 0;
				this.startTop = 0;
				this.isUp = true;
				this.isDrag = false;
				return;
			} else if (res) {
				this['top' + index] = v;
			} else if (!res) {
				this['top' + maxCurrent] = v - cardHeight;
			}
		},
		touchCancel: function(e, index) {
			let { isAnimating, current, data, isUp, left, maxCurrent, throwTriggerDistance } = this;
			if (isAnimating) return;
			if ((current >= data.length - 1 && isUp) || (current === 0 && !isUp)) {
				// console.log("touchCancel 不能点了");
				this['top' + index] = 0;
				this.startTop = 0;
				this.isUp = true;
				return;
			}

			// 重置卡片的状态
			// 当滑动距离不够的时候，要进行回弹
			let distance = this.getDistance(0, 0, left, isUp ? this['top' + index] : this['top' + maxCurrent]);
			if (distance > throwTriggerDistance) {
				this.makeCardThrow(index);
			} else {
				this.makeCardBack();
			}
		},
		makeCardThrow(index) {
			// 执行显示下一张卡片的操作
			let { isUp, current, data } = this;
			let newCurrent = 0;
			if (isUp) {
				if (current < data.length) {
					newCurrent = current + 1;
					if (data.length - current <= 6) {
						this.loadingMore();
					}
				}
			} else {
				if (current >= 1 && !isUp) {
					newCurrent = current - 1;
				}
			}

			this.isAnimating = true; // 开启 css动画（这里的动画是上滑动和下滑动的动画）
			this.currentIndex = index;
			this.current = newCurrent; // current修改的时候，class会切换，所以有切换动画
			let { baseCard0, baseCard1, baseCard2, baseCard3, baseCard4 } = this.$refs;
			setTimeout(() => {
				// 进行层级修改的时候不需要切换动画

				let max = 100;
				let min = 96;
				for (let i = 0; i < 5; i++) {
					// 切层级动画关闭
					if (isUp) {
						// 当往上滑动的时候
						if (this['zIndex' + i] == max) {
							this['zIndex' + i] = min;
							this['currentItem' + i] = data[newCurrent + 3];
						} else {
							this['zIndex' + i] = this['zIndex' + i] + 1;
						}
					} else {
						// 往下滑动
						if (this['zIndex' + i] == min) {
							this['zIndex' + i] = max;
							this['currentItem' + i] = data[newCurrent - 1];
						} else {
							this['zIndex' + i] = this['zIndex' + i] - 1;
						}
					}
				}

				for (let n = 0; n < 5; n++) {
					if (this['zIndex' + n] == min) {
						this.minCurrent = n;
					}
					if (this['zIndex' + n] == max) {
						this.maxCurrent = n;
						this['top' + n] = -2000;
					} else {
						this['top' + n] = 0;
					}
				}
				this.isAnimating = false; // 关闭css动画（这里的动画是上滑动和下滑动的动画）
			
			}, 200);

			this.isDrag = false;
			this.startTop = 0;
		},
		makeCardBack: function() {
			setTimeout(() => {
				this.isDrag = false;
				let { top0, top1, top2, top3, top4 } = this;
				this.top0 = top0 == -2000 ? -2000 : 0;
				this.top1 = top1 == -2000 ? -2000 : 0;
				this.top2 = top2 == -2000 ? -2000 : 0;
				this.top3 = top3 == -2000 ? -2000 : 0;
				this.top4 = top4 == -2000 ? -2000 : 0;
				this.startTop = 0;
				this.isUp = true;
			}, 200);
		},
		loadingMore() {
			this.$emit('loadingMore');
		}
	}
};
</script>

<style>
.ezfly-card-container {
	width: 100%;
	height: 100%;
	display: flex;
	justify-content: center;
}

.card {
	width: 80% !important;
	position: absolute;
	overflow: hidden;
	transform: translate3d(0, 0, 0);
	background: #fff;
	border-radius: 20rpx;
	box-shadow: 0 2rpx 10rpx 5rpx rgba(0, 0, 0, 0.24);
	transition: box-shadow 0.3s ease-in-out, transform 0.3s cubic-bezier(0.18, 1.06, 0.57, 0.92);
}

.card0 {
	z-index: 100;
	transform: translate3d(0, 0, 0) scale3d(1, 1, 1);
	opacity: 0;
}

.card1 {
	z-index: 99;
	transform: translate3d(0, 0, 0);
}

.card2 {
	z-index: 98;
	transform: translate3d(0, 4.4%, 0) scale3d(0.95, 0.95, 0.95);
}

.card3 {
	z-index: 97;
	transform: translate3d(0, 8.7%, 0) scale3d(0.9, 0.9, 0.9);
}

.card4 {
	z-index: 96;
	transform: translate3d(0, 8.7%, 0) scale3d(0.9, 0.9, 0.9);
	opacity: 0;
}

@keyframes mymove1 {
	from {
	}

	to {
		top: -2000px;
	}
}

@keyframes mymove2 {
	from {
		/* opacity: .5; */
	}

	to {
		top: 0;
		opacity: 1;
	}
}

.card.flying-up {
	animation: mymove1 0.7s forwards;
	animation-timing-function: ease;
}

.card.flying-down {
	animation: mymove2 0.2s forwards;
}
</style>
